<script lang="ts" setup>
import type {
  DynamicallyCrudOptions,
  ScopeContext,
} from '@fast-crud/fast-crud';

import type { Recordable } from '@vben/types';

import { h, reactive, ref } from 'vue';

import { useVbenModal } from '@vben/common-ui';

import { useFs } from '@fast-crud/fast-crud';
import { Button, Tag } from 'ant-design-vue';
import { cloneDeep } from 'lodash-es';

import { DefTenantApi, findOnlineServicePrefix } from '#/api';
import { TenantStatusEnum } from '#/enums/system';
import { useMessage } from '#/hooks/web/useMessage';

import { createCrudOptions } from '../data/link-data-source-crud';

defineOptions({
  name: '初始化企业数据库表结构和初始数据',
  inheritAttrs: false,
});
const emit = defineEmits<Emits>();
interface Emits {
  (e: 'success'): void;
}
const { createMessage } = useMessage();
const state = reactive<Recordable>({
  serviceMap: {},
  loading: {},
});

const formRef = ref();
const { crudExpose, resetCrudOptions, crudBinding, crudOptions } = useFs({
  createCrudOptions,
});

const [Modal, modalApi] = useVbenModal({
  async onOpenChange(isOpen) {
    if (isOpen) {
      modalApi.setState({ loading: false, confirmLoading: false });
      const record = modalApi.getData()?.record || {};

      const serviceMap = await findOnlineServicePrefix();
      state.serviceMap = serviceMap;

      const newOptions = cloneDeep<DynamicallyCrudOptions>(crudOptions);

      for (const key in serviceMap) {
        const servicePrefix = serviceMap[key] as unknown as string;

        state[servicePrefix] = await (servicePrefix === 'gateway'
          ? DefTenantApi.checkDs('', record.id)
          : DefTenantApi.checkDs(`/${servicePrefix}`, record.id));

        if (newOptions.columns) {
          // @ts-expect-error 不知道这里是什么错，暂时禁止报错...
          newOptions.columns[key] = {
            title: key,
            type: 'text',
            form: {
              render: (scope: ScopeContext) => {
                if (!state[servicePrefix]) {
                  return [
                    h(
                      Tag,
                      { color: state[servicePrefix] ? 'success' : 'error' },
                      {
                        default: () =>
                          state[servicePrefix] ? '已链接' : '未链接',
                      },
                    ),
                    h(
                      Button,
                      {
                        type: 'primary',
                        loading: state.loading[servicePrefix],
                        onClick: () =>
                          linkDataSource(key, servicePrefix, scope.form),
                      },
                      { default: () => '立即链接' },
                    ),
                  ];
                }

                return [
                  h(
                    Tag,
                    { color: state[servicePrefix] ? 'success' : 'error' },
                    {
                      default: () =>
                        state[servicePrefix] ? '已链接' : '未链接',
                    },
                  ),
                ];
              },
            },
          };
        }
      }

      resetCrudOptions(newOptions);
      crudExpose.doRefresh();
      formRef.value.setFormData({ ...record, status: TenantStatusEnum.NORMAL });
    }
  },
  async onConfirm() {
    try {
      modalApi.setState({ loading: true, confirmLoading: true });
      await formRef.value.submit();

      createMessage.success('初始化成功');
      modalApi.close();
      emit('success');
    } finally {
      modalApi.setState({ loading: false, confirmLoading: false });
    }
  },
});

async function linkDataSource(
  applicationName: string,
  servicePrefix: string,
  tenant: Recordable,
) {
  try {
    state.loading[servicePrefix] = true;
    state[servicePrefix] = await (servicePrefix === 'gateway'
      ? DefTenantApi.initDataSource('', tenant.id)
      : DefTenantApi.initDataSource(`/${servicePrefix}`, tenant.id));
    createMessage.success(`${applicationName}:已成功连接数据源`);
  } finally {
    state.loading[servicePrefix] = false;
  }
}
defineExpose(modalApi);
</script>

<template>
  <Modal title="初始化其他服务的数据源" class="w-[60%]">
    <div class="p-5">
      <FsForm ref="formRef" v-bind="crudBinding.editForm" />
    </div>
  </Modal>
</template>
